home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Comm / AmiTCP30b2.lha / src / appl / napsaterm / emulate.c < prev    next >
C/C++ Source or Header  |  1994-05-14  |  25KB  |  1,056 lines

  1. /* $Id: emulate.c,v 3.2 1994/05/14 11:10:58 ppessi Exp $
  2.  *
  3.  * emulate.c  -- key parsing for vt102/vt52/h19/etc  emulation
  4.  *
  5.  * (C) Copyright 1988, 1989 Chris Newman
  6.  * All Rights Reserved
  7.  * Permission is granted ot copy, modify, and use this as long
  8.  * as this notice remains intact.  This is a nifty program.
  9.  * 
  10.  * Doug's contribution: it
  11.  * "What do you mean? The implementation of scroll bars is trivial."
  12.  *
  13.  * $Log: emulate.c,v $
  14.  * Revision 3.2  1994/05/14  11:10:58  ppessi
  15.  * *** empty log message ***
  16.  *
  17.  * Revision 3.1  1994/05/12  10:14:56  ppessi
  18.  * Merged changes from Napsaterm 3.5 by R. Knop
  19.  *
  20.  */
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include "nifty.h"
  26. #include "display.h"
  27. #include "napsaprefs.h"
  28.  
  29. #define    MAXTERMBUF  300
  30. #define    MAXESCBUF   20
  31. #define    MAXARG        7
  32.  
  33. #define VT100ATTRIBS  "\033[?1;2c"
  34.  
  35. #define CSI '\233'
  36.  
  37. /* these are program global variables */
  38. int vt100_yucky_wrap_mode = 0;    /* vt100 wrap flag */
  39. /* these are local to this module */
  40. static int savecurset = 0;    /* area to save params */
  41. static int saveG[2] = {0, 1};    
  42. static int esc_mode;        /* current escape mode */
  43. static int private = 0;        /* private terminal modes -- 0, 1 = DEC, 2 = H19 */
  44. static int curarg, arg[MAXARG+1]; /* ANSI code arguments */
  45. static int curset = 0;        /* current VT100 character set */
  46. static int G[2] = {0, 1};    /* settings for 2 VT100 sets */
  47. static int sendgarbage    = 3;    /* if 2, terminal reports may be sent at times */
  48.  
  49. #if 0
  50. static char *termtype = "TERM=vt102";
  51. static char *termcap = "TERMCAP=dy|vt102|vt-102|wm|dec vt102:co#80:li#24:bw:am:xn:\
  52. \n\t:so=\\E[7m:se=\\E[27m:us=\\E[4m:ue=\\E[24m:ms:as=\\E)0^N:ae=\\E(B^O:\
  53. \n\t:md=\\E[1m:mr=\\E[7m:mb=\\E[5m:mt=\\E[3m:mk=\\E[8m:me=\\E[m:bc=^H:\
  54. \n\t:do=\\E[B:up=\\E[A:le=^H:nd=\\E[C:UP=\\E[%dA:DO=\\E[%dB:RI=\\E%dC:LE=\\E[%dD:\
  55. \n\t:cl=\\E[H\\E[2J:ho=\\E[H:cm=\\E[%i%d;%dH:cs=\\E[%i%d;%dr:IC=\\E[%d@:\
  56. \n\t:ce=\\E[K:cd=\\E[J:dc=\\E[P:DC=\\E[%dP:al=\\E[L:dl=\\E[M:rs=\\Ec:\
  57. \n\t:sc=\\E7:rc=\\E8:sf=\\ED:sr=\\EM:vb=\\EQ:AL=\\E[%dL:DL=\\E[%dM:\
  58. \n\t:im=\\E[4h:ei=\\E[4l:mi:km:ta=^I:";
  59. static char *h19termtype = "TERM=h19";
  60. static char *h19termcap = "TERMCAP=kb|h19|heath|zenith|z19|wm|heathkit h19:co#80:li#24:\
  61. \n\t:cr=^M:nl=^J:al=\\EL:am:le=^H:bs:cd=\\EJ:ce=\\EK:cl=\\EE:\
  62. \n\t:cm=\\EY%+ %+ :dc=\\EN:ei=\\EO:im=\\E@:mi:ta=^I:\
  63. \n\t:dl=\\EM:do=\\EB:ho=\\EH:mi:nd=\\EC:as=\\EF:ae=\\EG:ms:pt:sr=\\EI:\
  64. \n\t:se=\\Eq:so=\\Ep:up=\\EA:vs=\\Ex4:ve=\\Ey4:km:";
  65. static char *vt52termtype = "TERM=vt52";
  66. static char *vt52termcap = "TERMCAP=dw|vt52|vt-52|wm|dec vt52:\
  67. \n\t:do=^J:le=^H:bs:cd=\\EJ:ce=\\EK:cl=\\EH\\EJ:cm=\\EY%+ %+ :co#80:li#24:\
  68. \n\t:nd=\\EC:pt:sr=\\EI:up=\\EA:kb=^H:km:";
  69.  
  70. #endif
  71.  
  72. void docontrols(unsigned char c)
  73. {
  74. }
  75.  
  76. /* output characters to display
  77.  * the buffer text must have at least one extra byte after text+count
  78.  */
  79. #define    FLUSHBUF \
  80.    if (front < text) { *text = 0; dsputs(front); } front = text + 1
  81.  
  82. void termout(char *text, int count)
  83. {
  84.     unsigned char c;
  85.     char    *textend = text + count;
  86.     char    *front;
  87. #if 0
  88.     static char buffer[MAXTERMBUF];
  89.     char *bp = buffer, *bpend = buffer + MAXTERMBUF - 1; 
  90. #endif
  91.  
  92. #ifdef TEKTRONICS        /* added RKNOP 940328 */
  93.     /* May call termout recursively... hope that works */
  94.     if (tekmode)     
  95.     /* Actually, I don't think it will any more */
  96.     text = tekout(text,textend);   
  97. #endif                          /* End added RKNOP */
  98.     
  99.     dscursoroff();
  100.     for (front = text; text < textend; text++) {
  101. #ifdef TEKTRONICS        /* added RKNOP 940328 */
  102.         if (tekmode) {  
  103.         c = *text;
  104.         /* Get rid of all characters before the tek transition */
  105.         FLUSHBUF;        
  106.         /* Preserve *text, which is set to 0 in FLUSHBUF */
  107.         *text = c;      
  108.         text = tekout(text,textend);
  109.         front = text;    /* So we don't flush this twice */
  110.         if (text >= textend) 
  111.         break;
  112.         }
  113. #endif                /* end added RKNOP */
  114.     if (((c = *text ) & 127) >= ' ') {
  115.         if (!np.pass8) *text &= 127;
  116.         if (c == DEL) {
  117.         vt100_yucky_wrap_mode = 0;
  118.         FLUSHBUF;
  119.         continue;
  120.         } else if (esc_mode) {
  121.         vt100_yucky_wrap_mode = 0;
  122.         if (!decode_escapes(c))
  123.             front++;
  124.         } 
  125.         continue;
  126.     } else {
  127.         vt100_yucky_wrap_mode = 0;
  128.         FLUSHBUF;
  129.         switch (c) {
  130.         case CTRL('G'):
  131.         if (np.bell_type & 1)
  132.             dsinvert(VISUAL_BELL);
  133.         if (np.bell_type & 2)
  134.             audiobell();
  135.         if (np.bell_type & 4)
  136.             displaybell();
  137.         break;
  138.         
  139.         case CTRL('H'):    /* cursor left */
  140.         dscursormove(CURSOR_LEFT, 1);
  141.         break;
  142.  
  143.         case '\t':        /* tab */
  144.         dscursormove(TAB_STOP,0);
  145.         break;
  146.  
  147.         case CTRL('L'):    /* clear screen on h19 */
  148.         if (np.emulation == EMU_H19) {
  149.             dsclearscreen();
  150.             break;
  151.         }        /* fall through */
  152. #ifdef TEKTRONICS        /* Added RKNOP 940328 */
  153.                 else if (np.emulation == EMU_VT102) {  
  154.             /* ESC FF -- goto tek4010, clear tek window */
  155.             if (esc_mode == 1) {  
  156.             vt100_tek();
  157.             graph_clear();
  158.             }
  159.             break;
  160.                 }
  161. #endif                          /* End added RKNOP 940328 */
  162.         case CTRL('J'):
  163.         if (np.ansi_LNM && c == CTRL('J')) {
  164.             dscursormove(NEXT_LINE, 1);
  165.             break;
  166.         }        /* fall through */
  167.         case CTRL('K'):    /* cursor down w/ scroll */
  168.         if (!dscheckdown()) {
  169.             register char   *scan;
  170.             register int    retcnt = 1;
  171.  
  172.             for (scan = text+1; scan < textend && *scan != ESC; scan++)
  173.             if (*scan == CTRL('J') || *scan == CTRL('K'))
  174.                 retcnt++;
  175.             dscursormove(DOWN1_AND_SCROLL, retcnt);
  176.         }
  177.         break;
  178.  
  179.         case CTRL('M'):    /* CR / newline */
  180.         dscursormove(BEGIN_LINE, 0);
  181.         break;
  182.  
  183.         case CTRL('N'):    /* SI -- shift in alternate */
  184.         curset=1;
  185.         if (G[curset] || np.emulation == EMU_VT52)
  186.             (void) dsstyle(ALTERNATE1);
  187.         else
  188.             (void) dsstyle(ALTERNATE0);
  189.         break;
  190.  
  191.         case CTRL('O'):    /* SO -- shift out alternate */
  192.         curset=0;
  193.         if (G[curset] && np.emulation == EMU_VT102)
  194.             (void) dsstyle(ALTERNATE1);
  195.         else
  196.             (void) dsstyle(ALTERNATE0);
  197.         break;
  198.  
  199.         case CTRL('X'): case CTRL('Z'): /* cancel escape sequence */
  200.         esc_mode = 0;
  201.         break;
  202. #ifdef TEKTRONICS        /* Added RKNOP 940328 */
  203.             case CTRL('\\'):    /* FS */
  204.                 vt100_tek();
  205.                 set_tekmode(TEK_POINT);
  206.                 break;
  207.             case CTRL(']'):    /* GS */
  208.                 vt100_tek();
  209.                 set_tekmode(TEK_VECTOR);
  210.                 break;
  211.             case CTRL('^'):    /* RS */
  212.                 vt100_tek();
  213.                 set_tekmode(TEK_INCR);
  214.                 break;
  215.             case CTRL('_'):    /* US */
  216.                 vt100_tek();
  217.                 set_tekmode(TEK_ALPHA);
  218. #endif                         /* End added RKNOP */
  219.          
  220.         case CSI:
  221.         case ESC:        /* escape key */
  222.         switch (np.emulation) {
  223.         case EMU_VT102:
  224.             esc_mode = 1;
  225.             break;
  226.  
  227.         case EMU_VT52:
  228.             esc_mode = 10;
  229.             break;
  230.  
  231.         case EMU_H19:
  232.             esc_mode = 20;
  233.             break;
  234.         }
  235.         curarg = 0;
  236.         if (c == CSI)
  237.             decode_escapes('[');
  238.         break;
  239.         }
  240.     }
  241.     }
  242.     FLUSHBUF;
  243.     dscursoron();
  244. }
  245.  
  246. /***** look at the code for ts and fs and ds and is -- status line *****
  247.  */
  248.  
  249. /* terminal capabilites:
  250.  * co# -- number of columns, set on startup
  251.  * li# -- number of lines, set on startup
  252.  * bw -- cursor left is backspace
  253.  * am, xn -- Terminal wraps at 80 columns, only if two graphic characters are sent.
  254.  * mi,ms -- safe to move in insert/standout mode
  255.  * so,se -- standout (inverse video) characters start/end
  256.  * us,ue -- underline characters start/end
  257.  * as,ae -- enter/exit alternate character set
  258.  * md,mr,mb -- make dark (bold), make reverse (inverse), make blink (flash)
  259.  * mt,mk,me -- make iTalic, make blank, make styles end
  260.  * do,le, bc -- cursor down, cursor left, backspace character (same as cursor left).
  261.  * up,nd -- cursor up, cursor right (non-destructive space)
  262.  * UP, DO, RI, LE -- move up/down/right/left n characters
  263.  * cl,ho -- clear screen, home cursor
  264.  * ce,cd -- clear to end of line/display
  265.  * sc,rc -- save/recall cursor position
  266.  * cs -- change scrolling region
  267.  * rs -- reset terminal
  268.  * dc,DC -- delete character(s)
  269.  * IC -- insert character(s)
  270.  * al,AL,dl,DL -- add line(s), delete line(s)
  271.  * im, ei -- insert mode, end insert mode
  272.  * vs, ve -- very visual cursor, normal visual cursor
  273.  * sf, sr -- scroll forward/reverse.  Cursor must be at bottom/top of screen.
  274.  * vb -- visual bell
  275.  * cm -- cursor move
  276.  * ta,cr,nl -- tab/carriage return/new line
  277.  */
  278.  
  279. /* different terminal modes
  280.  */
  281. void terminalMode(int num, int private, int on)
  282. {
  283.     switch (private) {
  284.     case 0:    /* standard ansi modes */
  285.         switch (num) {
  286.         case 4:
  287.             dsfunction(on ? INSERT_ON : INSERT_OFF);
  288.             break;
  289.  
  290.         case 20:
  291.             np.ansi_LNM = on;
  292.             break;
  293.         }
  294.         break;
  295.  
  296.     case 1: /* vt100 private modes */
  297.         /* unimplemented modes:
  298.          * 3 - 80/132 column mode
  299.          * 4 - soft/jump scroll
  300.          */
  301.         switch (num) {
  302.         case 1:
  303.             dskeyboard(DS_KEYPADAPPMODE, on);
  304.             break;
  305.  
  306.         case 2:
  307.             if (!on)
  308.             np.emulation = EMU_VT52;
  309.             break;
  310.  
  311.         case 5:
  312.             dsinvert(on ? INVERT_ON : INVERT_OFF);
  313.             break;
  314.                 
  315.         case 6:
  316.             dsfunction(on ? ORIGIN_ON : ORIGIN_OFF);
  317.             break;
  318.  
  319.         case 7:
  320.             dsfunction(on ? WRAP_ON : WRAP_OFF);
  321.             break;
  322.  
  323.         case 8:
  324.             dskeyboard(DS_AUTOREPEAT, on);
  325.             break;
  326. #ifdef TEKTRONICS        /* added RKNOP 940328 */
  327.                 case 38:
  328.                     if (on)
  329.                        vt100_tek();
  330.                     break;
  331. #endif                          /* end added RKNOP 940328 */
  332.         }
  333.         break;
  334.  
  335.     case 2: /* h19 private modes */
  336.         /* modes not implemented:
  337.          * 1 - 25th line status (on -> enabled)
  338.          * 3 - hold screen mode
  339.          * 8 - auto linefeed on CR
  340.          * 9 - auto CR on linefeed
  341.          */
  342.         switch (num) {
  343.         case 2:
  344.             dskeyboard(DS_KEYCLICK, on ? 0 : 1);
  345.             break;
  346.  
  347.         case 4:
  348.             dsfunction(on ? BLOCK_CURSOR : UNDERLINE_CURSOR);
  349.             break;
  350.             
  351.         case 5:
  352.             dsfunction(on ? INVISIBLE_CURSOR : VISIBLE_CURSOR);
  353.             break;
  354.  
  355.         case 6:
  356.             dskeyboard(DS_KEYPADMODE, on ? KEYPAD_H19S : KEYPAD_H19);
  357.             break;
  358.  
  359.         case 7:
  360.             dskeyboard(DS_KEYPADAPPMODE, on);
  361.             break;
  362.         }
  363.         break;
  364.     }
  365. }
  366.  
  367. /* handle escape sequences
  368.  */
  369. int decode_escapes(c)
  370. char    c;
  371. {
  372.     int i, x, y;
  373.     
  374.     switch (esc_mode) {
  375.     case 1: /* escape key just pressed */
  376.         switch (c) {
  377.         case '[': /* ANSI sequence prefix */
  378.             for (i=0; i<=MAXARG; i++)
  379.             arg[i] = 0;
  380.             esc_mode = 2;
  381.             private = 0;
  382.             return (0);
  383.  
  384.         case '#': /* DEC Private line width modes */
  385.             esc_mode = 3;
  386.             return (0);
  387.  
  388.         case '(': /* SCS: select character set -- for G[0] set */
  389.             esc_mode = 4;
  390.             return (0);
  391.  
  392.         case ')': /* SCS: select character set -- for G[1] set */
  393.             esc_mode = 5;
  394.             return (0);
  395. #ifdef TEKTRONICS               /* Added RKNOP 940328 */
  396.                case '%':        /* Needed for VLT similar mode switching */
  397.                     esc_mode = 6;
  398.                     return(0);
  399. #endif
  400.         case 'D': /* IND (index): cursor down with scroll forward */
  401.             dscursormove(INDEX,0);
  402.             break;
  403.  
  404.         case 'E': /* NEL (next line): proper return */
  405.             dscursormove(NEXT_LINE,1);
  406.             break;
  407.  
  408.         case 'H': /* HTS horizontal tabulation set */
  409.             dsfunction(SET_TAB);
  410.             break;
  411.  
  412.         case 'M': /* RI (reverse index): cursor up with scroll reverse */
  413.             dscursormove(REVERSE_INDEX,0);
  414.             break;
  415.             
  416.         case 'Q': /* visual bell VT220 */
  417.             dsinvert(VISUAL_BELL);
  418.             break;
  419.  
  420.         case 'Z': /* DECID identify terminal */
  421.             (void) write_to_tty(VT100ATTRIBS,7);
  422.             break;
  423.  
  424. #ifdef TEKTRONICS        /* Added RKNOP 940328 */
  425.                 case '1':    /* GraphOn sequence to switch to graphics */
  426.                                                 /* screen */
  427.             if (np.emulation == EMU_VT102)
  428.             vt100_tek();
  429.             break;
  430. #endif                          /* end added RKNOP */
  431.  
  432.         case '7': /* DECSC save cursor position (DEC private) */
  433.             dscursormove(SAVE_CURSOR,0);
  434.             savecurset = curset;
  435.             saveG[0] = G[0];
  436.             saveG[1] = G[1];
  437.             break;
  438.  
  439.         case '8': /* DECRC restore cursor position (DEC private) */
  440.             dscursormove(RESTORE_CURSOR,0);
  441.             curset = savecurset;
  442.             G[0]=saveG[0];
  443.             G[1]=saveG[1];
  444.             break;
  445.  
  446.         case 'c': /* RIS reset to initial state */
  447.             dsfunction(RESET_DISPLAY);
  448.             break;
  449.         }
  450.         break;
  451.  
  452.     case 2: /* escape [ foo character */
  453.         switch (c) {
  454.         case ISDIGIT:
  455.             arg[curarg] *= 10;
  456.             arg[curarg] += c-'0';
  457.             return (0);
  458.  
  459.         case '?':
  460.             private = 1;
  461.             return (0);
  462.  
  463.         case '>':
  464.             private = 2;
  465.             return (0);
  466.             
  467.         case ';': /* get next parameter */
  468.             if (curarg < MAXARG)
  469.             arg[++curarg]=0;
  470.             return (0);
  471.  
  472.         case 'A': /* CUU cursor up */
  473.             dscursormove(CURSOR_UP, arg[0]);
  474.             break;
  475.  
  476.         case 'B': /* CUD cursor down */
  477.             dscursormove(CURSOR_DOWN, arg[0]);
  478.             break;
  479.  
  480.         case 'C': /* CUF cursor right/forward */
  481.             dscursormove(CURSOR_RIGHT, arg[0]);
  482.             break;
  483.  
  484.         case 'D': /* CUB cursor left/backward */
  485.             dscursormove(CURSOR_LEFT, arg[0]);
  486.             break;
  487.  
  488.         case 'H': case 'f': /* move cursor to specific position. CUP, HVP */
  489.             if (arg[0])  arg[0]--;
  490.             if (arg[1])  arg[1]--;
  491.             dscursorto(arg[1], arg[0]);
  492.             break;
  493.  
  494.         case 'J': /* ED clear to end of display. (erase in display) */
  495.             switch (arg[0]) {
  496.             case 0:
  497.                 dsfunction(ERASETO_EOS);
  498.                 break;
  499.  
  500.             case 1:
  501.                 dsfunction(ERASETO_SOS);
  502.                 break;
  503.  
  504.             case 2:
  505.                 dsclearscreen();
  506.                 break;
  507.             }
  508.             break;
  509.             
  510.         case 'K': /* EL clear to end of line. (erase in line) */
  511.             switch (arg[0]) {
  512.             case 0:
  513.                 dsfunction(ERASETO_EOL);
  514.                 break;
  515.  
  516.             case 1:
  517.                 dsfunction(ERASETO_SOL);
  518.                 break;
  519.  
  520.             case 2:
  521.                 dsfunction(ERASE_LINE);
  522.                 break;
  523.             }
  524.             break;
  525.  
  526.         case 'L': /* insert line VT102 */
  527.             dscursormove(INSERT_LINE, arg[0]);
  528.             break;
  529.  
  530.         case 'M': /* delete line VT102 */
  531.             dscursormove(DELETE_LINE, arg[0]);
  532.             break;
  533.  
  534.         case 'P': /* delete character VT102 */
  535.             if (!arg[0])
  536.             arg[0] = 1;
  537.             dsdelete(arg[0]);
  538.             break;
  539.  
  540.         case '@': /* ansi insert character */
  541.             dscursormove(INSERT_CHAR, arg[0]);
  542.             break;
  543.  
  544.         case 'c': /* DA Device Attributes request */
  545.             if (arg[0] == 0) {
  546.             (void) write_to_tty(VT100ATTRIBS,7);
  547.             }
  548.             break;
  549.  
  550.         case 'g': /* TBC tabulation clear */
  551.             dsgetcursor(&x, &y);
  552.             for (i=0; i<=curarg; i++) switch (arg[i]) {
  553.             case 0:
  554.                 dsfunction(CLEAR_TAB);
  555.                 break;
  556.  
  557.             case 3:
  558.                 dsfunction(CLEAR_ALL_TABS);
  559.             }
  560.             break;
  561.  
  562.         case 'h': /* SM set terminal mode */
  563.             for (i=0; i<=curarg; i++)
  564.             terminalMode(arg[i], private, 1);
  565.             break;
  566.  
  567.         case 'l': /* RM reset terminal mode */
  568.             for (i=0; i<=curarg; i++)
  569.             terminalMode(arg[i], private, 0);
  570.             break;
  571.             
  572.         case 'm': /* SGR styles (select graphic rendition) */
  573.             for (i=0; i<=curarg; i++)
  574.             vtstyle(arg[i]);
  575.             break;
  576.  
  577.         case 'n': /* DSR  Device status report */
  578.             for (i=0; i<=curarg; i++) switch (arg[i]) {
  579.             case 5:
  580.                 (void) write_to_tty("\033[0n",4);
  581.                 break;
  582.  
  583.             case 6: {
  584.                 char cursorpos[10];
  585.                 char *cpos;
  586.                 int tempx, tempy;
  587.  
  588.                 dsgetcursor(&tempx, &tempy);
  589.                 if (tempx == 0 && tempy == 0)
  590.                 (void) write_to_tty("\033[R",3);
  591.                 else {
  592.                 cursorpos[0] = '\033';
  593.                 cursorpos[1] = '[';
  594.                 (void) strcpy(cursorpos + 2, itos(tempy + 1));
  595.                 cpos = cursorpos + strlen(cursorpos);
  596.                 *cpos++ = ';';
  597.                 (void) strcpy(cpos, itos(tempx + 1));
  598.                 (void) strcat(cpos, "R");
  599.                 (void) write_to_tty(cursorpos, strlen(cursorpos));
  600.                 }
  601.                 break;
  602.                 }
  603.             }
  604.             break;
  605.  
  606.         case 'q': /* DECLL set LEDs on keyboard */
  607.             {
  608.             int leds = 0;
  609.  
  610.             for (i=0; i<=curarg; i++) {
  611.                 if (!arg[i])
  612.                     leds = 0;
  613.                 else if (arg[i] <= 4)
  614.                     leds |= 1 << (arg[i]-1);
  615.             }
  616.             dskeyboard(DS_LEDS, leds);
  617.             }
  618.             break;
  619.  
  620.         case 'r': /* DECSTBM set top and bottom margins (scrolling range) */
  621.             dssetscroll(arg[0],arg[1]);
  622.             break;
  623.  
  624.         case 'x': /* DECREQTPARM Request Terminal Parameters */
  625.             switch (arg[0]) {
  626.             case 0:
  627.                 sendgarbage=2;
  628.                 vtreport();
  629.                 break;
  630.  
  631.             case 1:
  632.                 sendgarbage=3;
  633.                 vtreport();
  634.                 break;
  635.             }
  636.             break;
  637.             
  638.         default:
  639.             break;
  640.         }
  641.         break;
  642.  
  643.     case 3: /* dec private codes for fonts */
  644.         switch(c) {
  645.         case '3':
  646.             (void) dsstyle(DWIDTHTOP);
  647.             break;
  648.  
  649.         case '4':
  650.             (void) dsstyle(DWIDTHBOT);
  651.             break;
  652.  
  653.         case '5':
  654.             (void) dsstyle(DWIDTH0);
  655.             break;
  656.  
  657.         case '6':
  658.             (void) dsstyle(DWIDTH1);
  659.             break;
  660.             
  661.         case '8':
  662.             dstestscreen();
  663.             break;
  664.         }
  665.         break;
  666.  
  667.     case 4: case 5: /* SCS: select character set: ESC( or ESC) */
  668.         switch (c) {
  669.         case 'A': case 'B': case '1': /* change to UK/US/other ROM set */
  670.             G[esc_mode - 4] = 0;
  671.             if (esc_mode - 4 == curset)
  672.             (void) dsstyle(ALTERNATE0);
  673.             break;
  674.  
  675.         case '0': case '2': /* change to graphic set/graphic ROM set */
  676.             G[esc_mode - 4] = 1;
  677.             if (esc_mode - 4 == curset)
  678.             (void) dsstyle(ALTERNATE1);
  679.             break;
  680.  
  681.         default:
  682.             esc_mode = 0;
  683.             return (1);
  684.         }
  685.         break;
  686.  
  687. #ifdef TEKTRONICS            /* Added RKNOP 940328 */
  688.         case 6:      /* ESC % */
  689.             switch (c) {
  690.         case '!': 
  691.         esc_mode = 7; 
  692.         return (0);
  693.         default: 
  694.         esc_mode = 0; 
  695.             }
  696.             break;
  697.  
  698.         case 7:      /* ESC %! */
  699.         esc_mode = 0;
  700.  
  701.             switch (c) {
  702.  
  703.         case '0': 
  704.         vt100_tek();
  705.         break;
  706.  
  707.         case '1': 
  708.         tek_vt100();
  709.         break;
  710.  
  711.         default:  
  712.             }
  713.             break;
  714. #endif                /* End added RKNOP */
  715.     case 10: /* VT52 emulation -- ESC just hit */
  716.         switch (c) {
  717.         case 'A': /* cursor up */
  718.             dscursormove(CURSOR_UP, 1);
  719.             break;
  720.  
  721.         case 'B': /* cursor down */
  722.             dscursormove(CURSOR_DOWN, 1);
  723.             break;
  724.  
  725.         case 'C': /* cursor right */
  726.             dscursormove(CURSOR_RIGHT, 1);
  727.             break;
  728.  
  729.         case 'D': /* cursor left */
  730.             dscursormove(CURSOR_LEFT, 1);
  731.             break;
  732.  
  733.         case 'F': /* alternate characters */
  734.             (void) dsstyle(ALTERNATE1);
  735.             break;
  736.  
  737.         case 'G': /* standard characters */
  738.             (void) dsstyle(ALTERNATE0);
  739.             break;
  740.  
  741.         case 'H': /* home cursor */
  742.             dscursorto(0,0);
  743.             break;
  744.  
  745.         case 'I': /* reverse line feed */
  746.             dscursormove(REVERSE_INDEX,1);
  747.             break;
  748.  
  749.         case 'J': /* erase to end of screen */
  750.             dsfunction(ERASETO_EOS);
  751.             break;
  752.  
  753.         case 'K': /* erase to end of line */
  754.             dsfunction(ERASETO_EOL);
  755.             break;
  756.  
  757.         case 'Y': /* move cursor to specific position */
  758.             esc_mode = 11;
  759.             return (0);
  760.  
  761.         case 'Z': /* Identify terminal sequence */
  762.             /* VT100 emulating a VT52 */
  763.             (void) write_to_tty("\033/Z",3); 
  764.             break;
  765.  
  766.         case '<': /* switch to ANSI mode */
  767.             np.emulation = EMU_VT102;
  768.             break;
  769.         }
  770.         break;
  771.  
  772.     case 11:
  773.         arg[0] = (c&0x7f) - ' ';
  774.         esc_mode = 12;
  775.         return (0);
  776.  
  777.     case 12:
  778.         arg[1] = (c&0x7f) - ' ';
  779.         dscursorto(arg[1], arg[0]);
  780.         break;
  781.  
  782.     case 20: /* H19 emulation -- ESC just hit */
  783.         /* here is a list of unimplemented escapes:
  784.          * <   enter ansi mode
  785.          * [   enter hold screen mode (implemented as ansi codes)
  786.          * \   exit hold screen mode
  787.          * }   inhibit keyboard output
  788.          * {   enable keyboard output
  789.          * ]   Transmit 25th line
  790.          * #   Transmit page
  791.          * r   Set baud rate
  792.          */
  793.         switch (c) {
  794.         case 'A': /* HCUU: cursor up */
  795.             dscursormove(CURSOR_UP, 1);
  796.             break;
  797.  
  798.         case 'B': /* HCUD: cursor down */
  799.             dscursormove(CURSOR_DOWN, 1);
  800.             break;
  801.  
  802.         case 'C': /* HCUF: cursor right */
  803.             dscursormove(CURSOR_RIGHT, 1);
  804.             break;
  805.  
  806.         case 'D': /* HCUB: cursor left */
  807.             dscursormove(CURSOR_LEFT, 1);
  808.             break;
  809.  
  810.         case 'E': /* HCD: clear screen */
  811.             dsclearscreen();
  812.             break;
  813.  
  814.         case 'F': /* HEGM: alternate characters */
  815.             (void) dsstyle(ALTERNATE1);
  816.             break;
  817.  
  818.         case 'G': /* HXGM: standard characters */
  819.             (void) dsstyle(ALTERNATE0);
  820.             break;
  821.  
  822.         case 'H': /* HCUH: home cursor */
  823.             dscursorto(0,0);
  824.             break;
  825.  
  826.         case 'I': /* HRI: reverse line feed */
  827.             dscursormove(REVERSE_INDEX,1);
  828.             break;
  829.  
  830.         case 'J': /* HEOP: erase to end of screen */
  831.             dsfunction(ERASETO_EOS);
  832.             break;
  833.  
  834.         case 'K': /* HEOL: erase to end of line */
  835.             dsfunction(ERASETO_EOL);
  836.             break;
  837.  
  838.         case 'L': /* HIL: add new blank line */
  839.             dscursormove(INSERT_LINE,1);
  840.             break;
  841.  
  842.         case 'M': /* HDL: delete line */
  843.             dscursormove(DELETE_LINE,1);
  844.             break;
  845.  
  846.         case 'N': /* HDCH: delete character */
  847.             dsdelete(1);
  848.             break;
  849.  
  850.         case 'O': /* HERM: end insert mode */
  851.             dsfunction(INSERT_OFF);
  852.             break;
  853.  
  854.         case 'Y': /* HDCA: move cursor to specific position */
  855.             esc_mode = 11;
  856.             return (0);
  857.  
  858.         case 'Z': /* HID: Identify terminal sequence */
  859.             (void) write_to_tty("\033/K",3); /* can be vt52 */
  860.             break;
  861.  
  862.         case '@': /* HEIM: begin insert mode */
  863.             dsfunction(INSERT_ON);
  864.             break;
  865.  
  866.         case '[': /* ANSI controls for fun */
  867.             for (i=0; i<=MAXARG; i++)
  868.             arg[i]=0;
  869.             esc_mode = 2;
  870.             private = 0;
  871.             return (0);
  872.  
  873.         case '=': /* HAKM: enter alternate keypad mode */
  874.             dskeyboard(DS_KEYPADAPPMODE, 1);
  875.             break;
  876.  
  877.         case '>': /* HXAM: exit alternate keypad mode */
  878.             dskeyboard(DS_KEYPADAPPMODE, 0);
  879.  
  880.         case 'b': /* HBD: erase to start of screen */
  881.             dsfunction(ERASETO_SOS);
  882.             break;
  883.  
  884.         case 'j': /* HSCP: save cursor position */
  885.             dscursormove(SAVE_CURSOR,0);
  886.             break;
  887.  
  888.         case 'k': /* HRCP: restore cursor position */
  889.             dscursormove(RESTORE_CURSOR,0);
  890.             break;
  891.  
  892.         case 'l': /* HEL: erase the current line */
  893.             dsfunction(ERASE_LINE);
  894.             break;
  895.  
  896.         case 'n': { /* HCPR: report cursor position */
  897.             char cursorpos[10];
  898.             int tempx, tempy;
  899.  
  900.             dsgetcursor(&tempx, &tempy);
  901.             cursorpos[0] = '\033';
  902.             cursorpos[1] = 'Y';
  903.             cursorpos[2] = tempy + ' ';
  904.             cursorpos[3] = tempx + ' ';
  905.             cursorpos[4] = 0;
  906.             (void) write_to_tty(cursorpos, strlen(cursorpos));
  907.             break;
  908.             }
  909.  
  910.         case 'o': /* HEBL: erase to the beginning of the line */
  911.             dsfunction(ERASETO_SOL);
  912.             break;
  913.  
  914.         case 'p': /* HERV: begin stand out mode */
  915.             (void) dsstyle(INVERSE1);
  916.             break;
  917.  
  918.         case 'q': /* HXRV: end stand out mode */
  919.             (void) dsstyle(INVERSE0);
  920.             break;
  921.  
  922.         case 't': /* HEKS: enter shifted keypad mode */
  923.             dskeyboard(DS_KEYPADMODE, KEYPAD_H19S);
  924.             break;
  925.  
  926.         case 'u': /* HXKS: exit shifted keypad mode */
  927.             dskeyboard(DS_KEYPADMODE, KEYPAD_H19);
  928.             break;
  929.  
  930.         case 'v': /* HEWA: wrap mode on */
  931.             dsfunction(WRAP_ON);
  932.             break;
  933.  
  934.         case 'w': /* HXWA: wrap mode off */
  935.             dsfunction(WRAP_OFF);
  936.             break;
  937.  
  938.         case 'x': /* HSM: set mode */
  939.             esc_mode = 21;
  940.             return (0);
  941.  
  942.         case 'y': /* HRM: reset mode */
  943.             esc_mode = 22;
  944.             return (0);
  945.  
  946.         case 'z': /* HRAM: reset to power-up config */
  947.             dsfunction(RESET_DISPLAY);
  948.             break;
  949.         }
  950.         break;
  951.  
  952.     case 21: case 22:
  953.         terminalMode(c - '0', 2, esc_mode == 21);
  954.         break;
  955.     }
  956.  
  957.     return (esc_mode = 0);
  958. }
  959.  
  960. /* send a DECREPTPARM report
  961.  */
  962. void
  963. vtreport(void)
  964. {
  965.     char report[20];
  966.     
  967.     (void) strcpy(report, "\033[0;1;1;88;88;1;0x");
  968.     report[2] = '0' + sendgarbage;
  969.     (void) write_to_tty(report, strlen(report));
  970. }
  971.  
  972. /* arguments for the style commands: SGR -- ESC [ param ; .. ; m
  973.  */
  974. void
  975. vtstyle(int c)
  976. {
  977.     switch (c) {
  978.     case 1:
  979.         (void) dsstyle(BOLD1);
  980.         break;
  981.     case 21:
  982.         (void) dsstyle(BOLD0);
  983.         break;
  984.     case 3:
  985.         (void) dsstyle(ITALIC1);
  986.         break;
  987.     case 23:
  988.         (void) dsstyle(ITALIC0);
  989.         break;
  990.     case 4:
  991.         (void) dsstyle(UNDERLINE1);
  992.         break;
  993.     case 24:
  994.         (void) dsstyle(UNDERLINE0);
  995.         break;
  996.     case 5:
  997.         (void) dsstyle(BLINK1);
  998.         break;
  999.     case 25:
  1000.         (void) dsstyle(BLINK0);
  1001.         break;
  1002.     case 7:
  1003.         (void) dsstyle(INVERSE1);
  1004.         break;
  1005.     case 27:
  1006.         (void) dsstyle(INVERSE0);
  1007.         break;
  1008.     case 8:
  1009.         (void) dsstyle(BLANK1);
  1010.         break;
  1011.     case 28:
  1012.         (void) dsstyle(BLANK0);
  1013.         break;
  1014.     case 0:
  1015.         (void) dsstyle(STYLESOFF);
  1016.         if (G[curset])
  1017.         (void) dsstyle(ALTERNATE1);
  1018.         else
  1019.         (void) dsstyle(ALTERNATE0);
  1020.         break;
  1021.     case 10:
  1022.         (void) dsstyle(ALTERNATE1);
  1023.         break;
  1024.     case 11:
  1025.         (void) dsstyle(ALTERNATE0);
  1026.         break;
  1027.     }
  1028. }
  1029.  
  1030. #if 0
  1031. /* set up termcap and termtype
  1032.  */
  1033. char *gettermcap()
  1034. {
  1035.     switch (np.emulation) {
  1036.     case EMU_H19:
  1037.         return (h19termcap);
  1038.     case EMU_VT52:
  1039.         return (vt52termcap);
  1040.     default:
  1041.         return (termcap);
  1042.     }
  1043. }
  1044. char *gettermtype()
  1045. {
  1046.     switch (np.emulation) {
  1047.     case EMU_H19:
  1048.         return (h19termtype);
  1049.     case EMU_VT52:
  1050.         return (vt52termtype);
  1051.     default:
  1052.         return (termtype);
  1053.     }
  1054. }
  1055. #endif
  1056.